#include <algorithm>
#include "3pdm_optimal_irreps.h"
#include "npdm_typedefs.h"

namespace Npdm {
//----------------------------------------------------------------------------------------------------------------------------------------------------------
// Constructor for 3PDM_index object.

ThreePdmBlueprint::ThreePdmBlueprint (int kmax) {

  std::vector< std::vector< std::tuple<int,CRE_DES> > > ijk_vec, lmn_vec;
  kmax_ = kmax;

  // Build creation 3-indices ordered by site
  get3opsPerms(ijk_vec,CREATION);
  // Build destruction 3-indices ordered by site
  get3opsPerms(lmn_vec,DESTRUCTION);

  buildIrrepOpStrings( ijk_vec, lmn_vec );
  buildDMRGmap();

}

//----------------------------------------------------------------------------------------------------------------------------------------------------------
// Build ordered non-zero permutations of 3 creation/des ops.
// Sorted by site-index

void ThreePdmBlueprint::get3opsPerms(std::vector< std::vector< std::tuple<int,CRE_DES> > > & pqr_vec, CRE_DES cre_des) {

  std::vector< std::tuple<int,CRE_DES> > ops(3, std::make_tuple(0,CREATION) );
  std::vector< std::tuple<int,CRE_DES> > tmp;

  for (int i=1; i<=kmax_ ; i++) {
    ops[0] = std::make_tuple(abs(i), cre_des);

    for (int j=i; j<=kmax_ ; j++) {
      ops[1] = std::make_tuple(abs(j), cre_des);

      for (int k=j; k<=kmax_ ; k++) {
        ops[2] = std::make_tuple(abs(k), cre_des);
        tmp = ops;
        std::sort( tmp.begin(), tmp.end() );
        pqr_vec.push_back( tmp );

      }
    }
  }

}

//----------------------------------------------------------------------------------------------------------------------------------------------------------
}
